#ifndef __WIZ_INNER_MEMORY_ALLOCATOR_LOKI_CHUNK_HPP__SHANHAOBO_19800429__
#define __WIZ_INNER_MEMORY_ALLOCATOR_LOKI_CHUNK_HPP__SHANHAOBO_19800429__

#include "../../../../../Include/Base/Type/WizBaseType.hpp"
#include "../../../../../Include/DataType/WizDataTypeRange.hpp"
#include "../../../../../Include/Core/Container/WizDataTypeMap.hpp"

#if (WIZ_DEBUG_MODE == WIZ_CFG_TRUE)
#include "../../../../../Include/Core/Container/WizDataTypeSet.hpp"
#endif /// #if (WIZ_DEBUG_MODE == WIZ_CFG_TRUE)

namespace Wiz
{
    namespace Inner
    {
        namespace Memory
        {
            namespace Allocator
            {
                namespace Loki
                {
                    namespace Chunk
                    {
                        class WIZ_PRIVATE Type
                        {
                            WIZ_DECLARE_CLASS_THIS(Type);

                        public:
                            Type(::Wiz::Size8::In EleSz, ::Wiz::Count8::In EleCnt);
                            ~Type();
                        public:
                            ::Wiz::Void::Ptr    Allocate();
                            ::Wiz::Void::Type   Deallocate(::Wiz::Void::Ptr);
#if (WIZ_DEBUG_MODE == WIZ_CFG_TRUE)
                        protected:
                            typedef ::Wiz::Set::Type<::Wiz::UInt8::Ptr> tDebugSet;
                            tDebugSet  m_AllocatedElement;
#endif /// #if (WIZ_DEBUG_MODE == WIZ_CFG_TRUE)
                        public:
                            ::Wiz::UInt8::FixedPtr      m_ElementPtr;
                            ::Wiz::UInt8::TypeConst     m_ElementSize;
                            ::Wiz::UInt8::TypeConst     m_ElementTotal;
                            ::Wiz::UInt8::Type          m_FirstAvailable;
                            ::Wiz::UInt8::Type          m_CountAvailable;
                        }; /// end of struct Type
                        WIZ_DECLARE(::Wiz::Inner::Memory::Allocator::Loki::Chunk::Type);

                        namespace Proxy
                        {
                            struct Type : public ::Wiz::Range::Type<::Wiz::UInt8::FixedConstPtr>
                            {
                                typedef ::Wiz::Range::Type<::Wiz::UInt8::FixedConstPtr> tSuper;
                                typedef Type                                            tThis;
                            public:
                                Type(::Wiz::UInt8::FixedConstPtr InBegin) : tSuper(InBegin, InBegin)
                                {
                                }
                                Type(::Wiz::UInt8::FixedConstPtr InBegin, ::Wiz::UInt8::FixedConstPtr InEnd) : tSuper(InBegin, InEnd)
                                {
                                }
                                Type(::Wiz::UInt8::FixedConstPtr InBegin, ::Wiz::Size::In InSZ) : tSuper(InBegin, InBegin + InSZ)
                                {
                                }
                                Type(::Wiz::Inner::Memory::Allocator::Loki::Chunk::In InChunk)
                                    : tSuper(InChunk.m_ElementPtr, InChunk.m_ElementPtr + (InChunk.m_ElementSize * InChunk.m_ElementTotal))
                                {
                                }
                            public:
                                friend ::Wiz::Bool::Type operator < (tThisIn InCmpr, tThisIn InStd)
                                {
                                    WIZ_ASSERT(InCmpr.IsValid());
                                    WIZ_ASSERT(InStd.IsValid());
                                    if (InCmpr.Begin() < InStd.Begin())
                                    {
                                        WIZ_ASSERT(InCmpr.End() < InStd.Begin());
                                        return ::Wiz::Bool::True;
                                    }
                                    return ::Wiz::Bool::False;
                                }
                                friend ::Wiz::Bool::Type operator == (tThisIn InCmpr, tThisIn InStd)
                                {
                                    WIZ_ASSERT(InCmpr.IsValid());
                                    WIZ_ASSERT(InStd.IsValid());
                                    if (InStd.IsBelongToMe(InCmpr.Begin()))
                                    {
                                        WIZ_ASSERT(InStd.IsBelongToMe(InCmpr.End()));
                                        return ::Wiz::Bool::True;
                                    }
                                    return ::Wiz::Bool::False;
                                }
                            private:
                                ::Wiz::UInt8::ConstPtr    m_Begin;
                                ::Wiz::UInt8::ConstPtr    m_End;
                            };
                            WIZ_DECLARE(::Wiz::Inner::Memory::Allocator::Loki::Chunk::Proxy::Type);
                        } /// end of namespace Proxy

                        namespace Map
                        {
                            typedef ::Wiz::Map::Type<::Wiz::Inner::Memory::Allocator::Loki::Chunk::Proxy::Type, ::Wiz::Inner::Memory::Allocator::Loki::Chunk::FixedPtr> Type;
                        } /// end of namespace Map
                    } /// end of namespace Chunk
                } /// end of namespace Loki
            } /// end of namespace Allocator
        } /// end of namespace Memory
    } /// end of namespace Inner
} /// end of namespace Wiz

#endif /*__WIZ_INNER_MEMORY_ALLOCATOR_LOKI_CHUNK_HPP__SHANHAOBO_19800429__*/

